using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using RichLabelSpace.Warp;

namespace RichLabelSpace
{
	public class RichLabelCtrl:MonoBehaviour
	{
		private bool m_is_busy = true;
        private Vector2 m_size = Vector2.zero;
        private NGUIText.Alignment m_alignment = NGUIText.Alignment.Automatic;
        private OnClickCallBack m_call_back = null;
        private string m_rich_txt = null;
        private Transform m_parent = null;
        private GameObject m_game_obj = null;
        private UIWidget m_widget = null;
        private RichLabelWarp m_rich_warp = null;
        private bool m_is_update = false;
        private bool m_is_update_pos = false;
        private List<List<RichLabelComponent>> m_lines = null;

        public GameObject GameObj { get { return this.m_game_obj; } }

		private List<RichLabelComponent> m_comps_list = new List<RichLabelComponent>();
        internal static readonly Dictionary<RichComponentType, RichTxtSign> rich_txt_sign_dict = new Dictionary<RichComponentType, RichTxtSign>{
            {RichComponentType.Label,new RichTxtSign("<label","/>")},
            {RichComponentType.Sprite,new RichTxtSign("<sprite","/>")},
            {RichComponentType.SpriteAmin,new RichTxtSign("<spamin","/>")},
            {RichComponentType.Texture,new RichTxtSign("<texture","/>")},
        };
		public bool IsBusy{get{return m_is_busy;}}

		public void Create(string rich_txt,Transform mnt,Vector2 size,NGUIText.Alignment alignment,OnClickCallBack call_back)
		{
            // 接入解析类
            this.m_rich_warp.Text = rich_txt;
            var list = this.m_rich_warp.RichStringList;
            var str = "";
            foreach (var item in list) str = str + item.Text;
            rich_txt = str;

            Debug.Log(str);
            ResetGameObj(this.m_game_obj, mnt);
            this.m_widget.width = (int)size.x;
            this.m_widget.height = (int)size.y;
            var rich_txts = RichTxtTool.SlipRichTxt(rich_txt);
            if (rich_txts == null || rich_txts.Length <= 0 ) return;

			this.m_is_busy = false;
            this.m_size = size;
            this.m_alignment = alignment;
            this.m_call_back = call_back;
            this.m_rich_txt = rich_txt;
            this.m_parent = mnt;

            foreach (var txt in rich_txts)
            {
                var temp_txt = txt;
                var comp_type = RichTxtTool.GetRichTextType(temp_txt);
                temp_txt = RichTxtTool.RemoveRichTextSign(temp_txt, comp_type);
                var comp = CreateRichComponent(this.m_game_obj.transform, comp_type, this);
                if (comp != null)
                {
                    if(comp.AnalyticRichTxt(temp_txt, comp_type))
                    {
                        comp.ExcuteSelf();
                        comp.Excute();
                        comp.InitEvent();
                    }
                    m_comps_list.Add(comp);
                }
            }

            m_is_update = true;
            //LateUpdate();
		}

        private void Push(List<List<RichLabelComponent>> lines) { this.m_lines = lines; }
        private List<List<RichLabelComponent>> Pop() {
            var lines = this.m_lines;
            this.m_lines = null;
            return lines;  
        }
        private void LateUpdate()
        {
            if (m_is_update)
            {
                Test.BeginSample("m_is_update");
                m_is_update = false;
                //// 延迟一帧执行
                //yield return null;
                var lines = RichCompSortHelper.ResetLines(this.m_size, this.m_comps_list);
                this.m_comps_list.Clear();
                for (int i = 0; i < lines.Count; ++i) this.m_comps_list.AddRange(lines[i]);
                Push(lines);
                m_is_update_pos = true;
                Test.EndSample("m_is_update");
            }

            if(m_is_update_pos)
            {
                Test.BeginSample("m_is_update_pos");
                var lines = Pop();
                m_is_update_pos = false;
                RichCompSortHelper.ResetPosition(this.m_parent, this.m_size, lines, this.m_alignment, 5);
                RichCompSortHelper.ResetDepth(this.m_comps_list);
                Test.EndSample("m_is_update_pos");
            }
        }

        private static RichLabelComponent CreateRichComponent(Transform child_mnt,RichComponentType comp_type,RichLabelCtrl ctrl)
        {
            RichLabelComponent comp = null;
            switch (comp_type)
            {
                case RichComponentType.Label:
                    comp = new RichLabel(child_mnt, ctrl);
                    break;
                case RichComponentType.Sprite:
                    comp = new RichSprite(child_mnt, ctrl);
                    break;
                case RichComponentType.SpriteAmin:
                    comp = new RichSpriteAnim(child_mnt, ctrl);
                    break;
                case RichComponentType.Texture:
                    comp = new RichTexture(child_mnt, ctrl);
                    break;
            }
            return comp;
        }

        internal void OnClick(string id)
        {
            foreach(var comp in m_comps_list)
            {
                if(comp.m_rich_event.CanClick && comp.m_rich_event.Id.Equals(id))
                {
                    comp.OnClick();
                }
            }
            if (this.m_call_back != null) m_call_back(id);
        }

		// 清理richlab,但是不回收
		public void Clear()
		{
            foreach(var comp in m_comps_list)
            {
                comp.Remove();
            }

            m_comps_list.Clear();
		}

		// 清理richlab,并且回收
		public void Free()
		{
			m_is_busy = true;
		}

        public string GetText()
        {
            return this.m_rich_warp.Text;
        }

        internal static void ResetGameObj(GameObject go, Transform mnt)
        {
            go.transform.SetParent(mnt);
            go.transform.localPosition = Vector3.zero;
            go.transform.localScale = Vector3.one;
            go.transform.localEulerAngles = Vector3.zero;
            
        }

        public static RichLabelCtrl CreateRichLabelCtrl()
        {
            var go = new GameObject();
            var go_name = "RichLabelCtrl";
            var widget = go.AddComponent<UIWidget>();
            var pivot = UIWidget.Pivot.TopLeft;
            var ctrl = go.AddComponent<RichLabelCtrl>();
            ctrl.Init(go, go_name, widget, pivot, ctrl);

            return ctrl;
        }

        private void Init(GameObject go, string go_name, UIWidget widget, UIWidget.Pivot pivot, RichLabelCtrl ctrl)
        {
            this.m_game_obj = go;
            this.m_game_obj.name = go_name;
            this.m_widget = widget;
            this.m_widget.pivot = pivot;
            this.m_rich_warp = new RichLabelWarp();
        }
	}
}
